package org.dromara.app.controller.admin;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.app.domain.bo.AppUserBo;
import org.dromara.app.domain.vo.AppUserVo;
import org.dromara.app.service.AppUserService;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.web.core.BaseController;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 管理端用户信息
 *
 * @author ruoyi
 */
@Tag(name = "管理端用户管理", description = "管理端用户信息管理接口")
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/admin/user")
public class AdminUserController extends BaseController {

    private final AppUserService appUserService;

    /**
     * 查询管理端用户信息列表
     */
    @Operation(summary = "查询用户列表", description = "分页查询管理端用户信息列表")
    @SaCheckPermission("admin:user:list")
    @GetMapping("/list")
    public TableDataInfo<AppUserVo> list(@Parameter(description = "用户查询条件") AppUserBo bo, 
                                         @Parameter(description = "分页参数") PageQuery pageQuery) {
        return appUserService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出管理端用户信息列表
     */
    @Operation(summary = "导出用户列表", description = "导出管理端用户信息到Excel")
    @SaCheckPermission("admin:user:export")
    @Log(title = "管理端用户信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(@Parameter(description = "用户查询条件") AppUserBo bo, 
                       @Parameter(description = "响应对象") HttpServletResponse response) {
        List<AppUserVo> list = appUserService.queryList(bo);
        ExcelUtil.exportExcel(list, "管理端用户信息", AppUserVo.class, response);
    }

    /**
     * 获取管理端用户信息详细信息
     */
    @Operation(summary = "获取用户详情", description = "根据用户ID获取详细信息")
    @SaCheckPermission("admin:user:query")
    @GetMapping("/{userId}")
    public R<AppUserVo> getInfo(@Parameter(description = "用户ID", required = true) 
                                @NotNull(message = "主键不能为空")
                                @PathVariable Long userId) {
        return R.ok(appUserService.queryById(userId));
    }

    /**
     * 新增管理端用户信息
     */
    @Operation(summary = "新增用户", description = "新增管理端用户信息")
    @SaCheckPermission("admin:user:add")
    @Log(title = "管理端用户信息", businessType = BusinessType.INSERT)
    @PostMapping()
    public R<Void> add(@Parameter(description = "用户信息", required = true) 
                       @Validated(AddGroup.class) @RequestBody AppUserBo bo) {
        return toAjax(appUserService.insertByBo(bo));
    }

    /**
     * 修改管理端用户信息
     */
    @Operation(summary = "修改用户", description = "修改管理端用户信息")
    @SaCheckPermission("admin:user:edit")
    @Log(title = "管理端用户信息", businessType = BusinessType.UPDATE)
    @PutMapping()
    public R<Void> edit(@Parameter(description = "用户信息", required = true) 
                        @Validated(EditGroup.class) @RequestBody AppUserBo bo) {
        return toAjax(appUserService.updateByBo(bo));
    }

    /**
     * 删除管理端用户信息
     */
    @Operation(summary = "删除用户", description = "批量删除管理端用户信息")
    @SaCheckPermission("admin:user:remove")
    @Log(title = "管理端用户信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{userIds}")
    public R<Void> remove(@Parameter(description = "用户ID数组", required = true) 
                          @NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] userIds) {
        return toAjax(appUserService.deleteWithValidByIds(List.of(userIds), true));
    }

    /**
     * 获取个人信息
     */
    @Operation(summary = "获取个人信息", description = "获取当前登录用户的个人信息")
    @GetMapping("/profile")
    public R<AppUserVo> profile() {
        LoginUser loginUser = LoginHelper.getLoginUser();
        AppUserVo user = appUserService.queryById(loginUser.getUserId());
        return R.ok(user);
    }

    /**
     * 修改个人信息
     */
    @Operation(summary = "修改个人信息", description = "修改当前登录用户的个人信息")
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PutMapping("/profile")
    public R<Void> updateProfile(@Parameter(description = "用户信息", required = true) 
                                 @RequestBody AppUserBo bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        bo.setUserId(loginUser.getUserId());
        return toAjax(appUserService.updateByBo(bo));
    }

    /**
     * 重置密码
     */
    @Operation(summary = "重置密码", description = "重置用户密码")
    @SaCheckPermission("admin:user:resetPwd")
    @Log(title = "管理端用户信息", businessType = BusinessType.UPDATE)
    @PutMapping("/resetPwd")
    public R<Void> resetPwd(@Parameter(description = "用户信息", required = true) 
                            @RequestBody AppUserBo bo) {
        AppUserBo userBo = new AppUserBo();
        userBo.setUserId(bo.getUserId());
        userBo.setPassword(bo.getPassword());
        return toAjax(appUserService.updateByBo(userBo));
    }

    /**
     * 状态修改
     */
    @Operation(summary = "修改用户状态", description = "修改用户启用/禁用状态")
    @SaCheckPermission("admin:user:edit")
    @Log(title = "管理端用户信息", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public R<Void> changeStatus(@Parameter(description = "用户信息", required = true) 
                                @RequestBody AppUserBo bo) {
        return toAjax(appUserService.updateUserStatus(bo.getUserId(), bo.getStatus()));
    }

    /**
     * 根据用户编号获取授权角色
     */
    @Operation(summary = "获取用户角色", description = "根据用户ID获取授权角色信息")
    @SaCheckPermission("admin:user:query")
    @GetMapping("/authRole/{userId}")
    public R<AppUserVo> authRole(@Parameter(description = "用户ID", required = true) 
                                 @PathVariable Long userId) {
        AppUserVo user = appUserService.queryById(userId);
        return R.ok(user);
    }

    /**
     * 获取部门树列表
     */
    @Operation(summary = "获取部门树", description = "获取部门树形结构列表")
    @SaCheckPermission("admin:user:list")
    @GetMapping("/deptTree")
    public R<List<Object>> deptTree(@Parameter(description = "用户查询条件") AppUserBo bo) {
        // 这里可以根据实际需求实现部门树逻辑
        return R.ok();
    }

}